﻿using System.Diagnostics.Contracts;
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#else
using System.Windows;
using System.Windows.Controls;
#endif

namespace DaveSexton.Labs
{
	/// <summary>
	/// When used in a Silverlight lab, ensures that the lab is only shown when the application is running 
	/// in Out-of-Browser mode.
	/// </summary>
	/// <remarks>
	/// <para>
	/// If the application is not running in Out-of-Browser mode, then the lab's UI is hidden and the user is 
	/// instead presented with instructions to either install the application or to launch the application, 
	/// depending upon whether it's already installed.
	/// </para>
	/// <alert type="note">
	/// <see cref="OutOfBrowserContentControl"/> is only meaningful in Silverlight labs; however, it is available 
	/// on all supported platforms to facilitate linking XAML files between projects.  For non-Silverlight labs, 
	/// it behaves identically to <see cref="ContentControl"/> with its <see cref="VerticalContentAlignment"/> and 
	/// <see cref="HorizontalContentAlignment"/> properties set to <strong>Stretch</strong> by default.
	/// </alert>
	/// </remarks>
	public class OutOfBrowserContentControl : ContentControl
	{
		#region Public Properties
		public virtual string ApplicationName
		{
			get
			{
				Contract.Ensures(Contract.Result<string>() != null);

#if NETFX_CORE
#elif WINDOWS_PHONE
#elif SILVERLIGHT
				var settings = OutOfBrowserSettings;

				if (settings != null)
				{
					return settings.ShortName ?? string.Empty;
				}
#else
				var window = Application.MainWindow;

				if (window != null)
				{
					return window.Title ?? string.Empty;
				}
#endif

				return string.Empty;
			}
		}

#if SILVERLIGHT && !WINDOWS_PHONE
		public static readonly DependencyProperty ReasonProperty = DependencyProperty.Register(
			"Reason",
			typeof(OutOfBrowserReason),
			typeof(OutOfBrowserContentControl),
			new PropertyMetadata(OutOfBrowserReason.ElevatedTrust));

		[ContractVerification(false)]
		public OutOfBrowserReason Reason
		{
			get
			{
				return (OutOfBrowserReason) GetValue(ReasonProperty);
			}
			set
			{
				SetValue(ReasonProperty, value);
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
			Justification = "UI binding.")]
		public bool IsRunningOutOfBrowser
		{
			get
			{
				return System.ComponentModel.DesignerProperties.IsInDesignTool
						|| Application.IsRunningOutOfBrowser;
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic",
			Justification = "UI binding.")]
		public bool IsInstalled
		{
			get
			{
				return Application.InstallState == InstallState.Installed;
			}
		}
#endif
		#endregion

		#region Private / Protected
		protected static Application Application
		{
			get
			{
				Contract.Ensures(Contract.Result<Application>() != null);

				var value = Application.Current;

#if SILVERLIGHT
				Contract.Assume(value != null);
#endif

				return value;
			}
		}

#if SILVERLIGHT && !WINDOWS_PHONE
		protected static OutOfBrowserSettings OutOfBrowserSettings
		{
			get
			{
				var deployment = Deployment.Current;

				if (deployment != null)
				{
					return deployment.OutOfBrowserSettings;
				}

				return null;
			}
		}
#endif
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="OutOfBrowserContentControl" /> class.
		/// </summary>
		public OutOfBrowserContentControl()
		{
#if SILVERLIGHT && !WINDOWS_PHONE
			DefaultStyleKey = typeof(OutOfBrowserContentControl);
#endif

			VerticalContentAlignment = VerticalAlignment.Stretch;
			HorizontalContentAlignment = HorizontalAlignment.Stretch;
		}
		#endregion

		#region Methods
		#endregion

		#region Event Handlers
		#endregion
	}
}